#include <fstream>   // file I/O
#include <iomanip>   // format manipulation
#include <string>
#include <list>
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <math.h>
#include "./classes/matriz.h"
#include "./classes/pgm.h"

using namespace std;


double* tc(unsigned short* xi, Matriz A, int k){
	double* res = new double[k];
	int vectorSize = A.m;
	for(int i = 1; i<k; i++){
		res[i-1] = 0;
		for(int j = 0; j<vectorSize; j++){
			res[i-1] += A(1,j+1) * xi[j];
		}
	}

	return res;
}

bool comparar(double* a, double* b, int n){
	double normaA = 0, normaB = 0;
	for(int i=0; i<n; i++){
		normaA += a[i]*a[i];
		normaB += b[i]*b[i];
	}
	normaA = sqrt(normaA);
	normaB = sqrt(normaB);
	
	return (normaA-normaB <= 0.2);
}

int main()
{
	cout << "TP3 - Laboratorio Métodos Numéricos"<<endl<<endl;
	
	int k = 1;
	int cantCaras = 2;
    
	char* muestraPath = "../Base_de_caras_1/face_01.pgm";
	PGM muestra(muestraPath);
	unsigned short* muestraCara = muestra.getData();
    
	PGM foto("../Base_de_caras_1/face_01.pgm");
	//unsigned short* img = foto.getData();
    
	int imSize = foto.height * foto.width;
	Matriz caras(cantCaras, imSize);
	
	unsigned short* u = new unsigned short[imSize];
	for(int j = 0; j<imSize;j++){
		u[j] = 0;
	}
    char base[80];
	strcpy (base,"../Base_de_caras_1/face_");
	for(int k = 1; k<=cantCaras; k++){
		char numero[2];
		sprintf(numero,"%d",k);
		
		if(k<10){
			strcpy (base,"../Base_de_caras_1/face_0");
		}else{
			strcpy (base,"../Base_de_caras_1/face_");
		}
		strcat(base, numero);
		strcat(base, ".pgm");
		PGM pic(base);
		unsigned short* img = pic.getData();
		for(int i = 0; i<imSize;i++){
			caras.setPos(k,i+1,img[i]);
			u[i] += img[i]/cantCaras;
		}
	}

	Matriz M(imSize,imSize);
	Matriz A(imSize,1);
	Matriz B(1,imSize);
    
	for(int k = 1; k<=cantCaras; k++){

		for(int i = 1; i<=imSize;i++){
			A.setPos(i,1,caras(k,i) - u[i]);
			B.setPos(1,i,caras(k,i) - u[i]);
		}
		M = M.suma((A.producto2(B)));
	}
    
	M = M.division(cantCaras-1);
    
    k=cantCaras;
    unsigned int alpha =0;
    double tolerancia = 0.1;
	Matriz autovectores = M.getKAutovectores(M, k, alpha, tolerancia);
	unsigned short cara[imSize];
	bool encontro = false;
	int i;
	for(i=1; i<=cantCaras; i++){
		for(int j=0; j<imSize; j++){
			cara[j] = (unsigned short)caras(i,j+1);
		}
		encontro = comparar(tc(cara, autovectores, k), tc(muestraCara, autovectores, k), k);
		if(encontro)
			break;
	}
    
	if(encontro){
		cout<< "Es la cara "<<i<<endl;
	}else{
		cout<<"No se encontro la cara"<<endl;
	}
	
	
	 
	return 0;
}
